package com.lecture.junit.tdd.example;


import java.util.Calendar;
import java.util.concurrent.atomic.AtomicInteger;

public abstract class LoginServiceState {

    AtomicInteger count;    
    public static final int MAX_DAYS_SINCE_LAST_USE = 45;
    
    public void login(LoginServiceInterface context, IAccount acc, String password) {
    	
        if (acc.containsUsedPassword(password)){
        	throw new PasswordRecentlyUsedException();
        } else if (acc.passwordMatches(password)) {
        	if (acc.isLoggedIn()) {
                throw new AccountAlreadyLoggedInException();
            }
            if (acc.isRevoked()) {
                throw new AccountIsRevokedException();
            }
            if (acc.isPasswordExpired()){
            	context.setState(acc.getUserName(), new MustChangePasswordBeforeLogin());
            	throw new PasswordExpiredException();
            }
            if ( Calendar.YEAR != acc.getTimeStamp().getYear()
            		||  ( Calendar.YEAR == acc.getTimeStamp().getYear() && 
            			Calendar.DAY_OF_YEAR - acc.getTimeStamp().getDayOfYear() 
            			> MAX_DAYS_SINCE_LAST_USE)) {
				acc.setRevoked();
			} else {
				acc.setLoggedIn();
			    acc.refreshTimeStamp();
			    context.setState(acc.getUserName(), new AwaitFirstLoginAttempt());
			}
        } else {
            handlePasswordFail(context, acc);
        }
    }

    protected abstract void handlePasswordFail(LoginServiceInterface context, IAccount acc);
}
